#include "ntp_manager.h"
#include "common_config_manager.h"
#include "utils_log.h"
#include <sstream>
#include <cstdlib>

namespace El {
namespace Network {

NtpManager& NtpManager::GetInstance()
{
    static NtpManager instance;
    return instance;
}

bool NtpManager::Start()
{
    std::lock_guard<std::mutex> lock(mutex_);
    
    if (initialized_) {
        EL_INFO("NTP管理器已经初始化");
        return true;
    }
    
    EL_INFO("启动NTP服务");

    // 注册配置变更回调
    ntpConfigHandle_ = Common::ConfigManager::GetInstance().Register(
        "/ntp",
        [this](const nlohmann::json& config) {
            EL_DEBUG("NTP验证回调触发，配置：{}", config.dump().c_str());
            EL_INFO("NTP配置变更：{}", config.dump().c_str());
            HandleNtpConfigChange(config);
            return true;
        },
        Common::ConfigPriority::APPLY);

    nlohmann::json config = Common::ConfigManager::GetInstance().GetConfig("/ntp");
    HandleNtpConfigChange(config);

    initialized_ = true;
    return true;
}

void NtpManager::Stop()
{
    std::lock_guard<std::mutex> lock(mutex_);
    
    if (!initialized_) {
        return;
    }
    
    EL_INFO("停止NTP服务");
    
    // 取消注册配置监听器
    if (ntpConfigHandle_ != -1) {
        auto& configManager = Common::ConfigManager::GetInstance();
        configManager.Unregister("/ntp", ntpConfigHandle_);
        ntpConfigHandle_ = -1;
    }
    
    StopNtpd();
    initialized_ = false;
}

void NtpManager::HandleNtpConfigChange(const nlohmann::json& config)
{
    if (config.is_null()) {
        EL_ERROR("HandleNtpConfigChange中获取ntp配置失败");
        StopNtpd();
        return;
    }

    // 检查是否启用NTP
    if (!config.value("enable", false)) {
        EL_INFO("NTP服务在配置中已禁用，停止服务");
        StopNtpd();
        return;
    }

    // 获取NTP服务器列表
    std::vector<std::string> servers;
    if (config.contains("servers") && config["servers"].is_array()) {
        for (const auto& server : config["servers"]) {
            if (server.is_string()) {
                servers.push_back(server.get<std::string>());
            }
        }
    }

    // 如果没有配置服务器，则使用默认值
    if (servers.empty()) {
        EL_ERROR("未配置NTP服务器，使用默认的cn.pool.ntp.org作为备用");
        servers.push_back("cn.pool.ntp.org");
    }

    // 先停止现有服务，再启动新服务
    EL_INFO("重新配置NTP服务");
    StopNtpd();
    StartNtpd(servers);
}

bool NtpManager::StartNtpd(const std::vector<std::string>& servers)
{
    // 构建ntpd命令
    std::stringstream cmdStream;
    // 使用 -g 允许初始较大的时间偏差调整，-N 提高优先级，-n 不 fork
    cmdStream << "ntpd -gNn";
    for (const auto& server : servers) {
        cmdStream << " -p " << server;
    }
    cmdStream << " &"; // 在后台运行

    std::string command = cmdStream.str();

    EL_INFO("启动ntpd服务，命令：'{}'", command);
    int ret = std::system(command.c_str());
    if (ret != 0) {
        EL_ERROR("启动ntpd服务失败，命令：'{}'，返回码：{}", command, ret);
        return false;
    } else {
        EL_INFO("ntpd服务启动成功");
        return true;
    }
}

bool NtpManager::StopNtpd()
{
    EL_INFO("停止ntpd服务");
    int ret = std::system("killall ntpd > /dev/null 2>&1");
    if (ret != 0) {
        // killall在找不到进程时也会返回非0，这不一定是错误
        EL_DEBUG("killall ntpd命令返回：{}", ret);
    } else {
        EL_INFO("通过killall停止ntpd服务成功");
    }
    return true;
}

} // namespace Network
} // namespace El